package com.ctl.jvm.jmh;

/**
 * <p>Title: d</p>
 * <p>Description: </p>
 * <p>Copyright: Copyright (c) 2019</p>
 * <p>Company: www.ctl.com</p>
 *
 * @author ctl
 * @version 1.1
 * @date 2024-07-04 10:34
 */

import org.openjdk.jmh.annotations.Mode;
import org.openjdk.jmh.results.format.ResultFormatType;
import org.openjdk.jmh.runner.Runner;
import org.openjdk.jmh.runner.RunnerException;
import org.openjdk.jmh.runner.options.ChainedOptionsBuilder;
import org.openjdk.jmh.runner.options.OptionsBuilder;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.concurrent.TimeUnit;


/**
 * OptionsTests
 * created at 2021/4/25
 *
 * @author weny
 * @since 1.0.0
 */
public class TestsMain {

    //生成的文件路径：{工程根目录}/{reportFileDir}/{XXX.class.getSimpleName()}.json
    // e.g. jmh-reports/EmptyMethod.json
    private static final String reportFileDir = "./";
//    private static final String reportPath = "sample-options-result.json";//生成的文件在工程根目录

    /*
     * ============================== HOW TO RUN THIS TEST: ====================================
     * 1. 修改 Class<IntegerSumTests> targetClazz = IntegerSumTests.class;//需要运行 JMH 测试的类
     * 2. 在 IDE 中运行 main 方法
     */

    public static void main(String[] args) throws RunnerException {
        Class<IntegerSumTests> targetClazz = IntegerSumTests.class;//需要运行 JMH 测试的类
        String reportFilePath = setupStandardOptions(targetClazz);
        System.out.println(Files.exists(Paths.get(reportFilePath)));
    }

    /**
     * 最基础的配置，目的是以最短的耗时测试 JMH 是否可以正常运行
     *
     * @param targetClazz 要运行 JMH 测试的类
     * @throws RunnerException See:{@link RunnerException}
     */
    @SuppressWarnings({"unused"})
    private static String setupBasicOptions(Class<?> targetClazz) throws RunnerException {
        // number of iterations is kept to a minimum just to verify that the benchmarks work without spending extra
        // time during builds.
        String reportFilePath = resolvePath(targetClazz);
        ChainedOptionsBuilder optionsBuilder =
                new OptionsBuilder()
                        .include(targetClazz.getSimpleName())
                        .forks(1)
                        .warmupIterations(0)
                        .measurementBatchSize(1)
                        .measurementIterations(1)
                        .shouldFailOnError(true)
                        .result(reportFilePath)
                        .timeUnit(TimeUnit.MICROSECONDS)
                        .resultFormat(ResultFormatType.JSON);
        new Runner(optionsBuilder.build()).run();
        return reportFilePath;
    }

    /**
     * 一份标准的配置，根据实际需求配置预热和迭代等参数
     *
     * @param targetClazz 要运行 JMH 测试的类
     * @throws RunnerException See:{@link RunnerException}
     */
    private static String setupStandardOptions(Class<?> targetClazz) throws RunnerException {
        String reportFilePath = resolvePath(targetClazz);
        ChainedOptionsBuilder optionsBuilder =
                new OptionsBuilder()
                        .include(targetClazz.getSimpleName())
                        .mode(Mode.Throughput)//模式-吞吐量 ｜ 注解方式 @BenchmarkMode(Mode.Throughput)
                        .forks(1)//Fork进行的数目 ｜ 注解方式 @Fork(2)
                        .warmupIterations(1)//预热轮数 ｜ 注解方式 @Warmup(iterations = 1)
                        .measurementIterations(3)//度量轮数 ｜ 注解方式 @Measurement(iterations = 3)
                        .timeUnit(TimeUnit.MICROSECONDS)//结果所使用的时间单位 | 注解方式 @OutputTimeUnit(TimeUnit.MILLISECONDS)
                        .shouldFailOnError(true)
                        .result(reportFilePath)//结果报告文件输出路径
                        .resultFormat(ResultFormatType.JSON);//结果报告文件输出格式 JSON
        new Runner(optionsBuilder.build()).run();
        return reportFilePath;
    }

    private static String resolvePath(Class<?> targetClazz) {
        return reportFileDir + targetClazz.getSimpleName() + ".json";
    }

}
